/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Main.java
 *
 * Created on Dec 25, 2011, 10:17:47 AM
 */
package zwritetrainer;

import java.io.*;
import javax.imageio.*;
import java.util.*;
import javax.swing.*;
import org.encog.neural.networks.BasicNetwork;
import org.encog.neural.networks.training.lma.LevenbergMarquardtTraining;
import org.encog.neural.networks.training.propagation.resilient.ResilientPropagation;
import org.encog.ml.data.MLData;
import org.encog.persist.EncogDirectoryPersistence;
import org.encog.engine.network.activation.*;
import org.encog.ml.data.MLDataSet;
import org.encog.ml.data.basic.BasicMLDataSet;
import org.encog.ml.train.MLTrain;
import org.encog.neural.networks.layers.BasicLayer;

/**
 *
 * @author Zelic
 */
public class Main extends javax.swing.JFrame {

    private String[] charArray = new String[]{
        "A", "Ă", "Â", "B", "C", "D", "Đ",
        "E", "Ê", "F", "G", "H", "K", "I",
        "J", "L", "M", "N", "O", "Ô", "Ơ",
        "P", "Q", "R", "S", "T", "U", "Ư",
        "V", "W", "X", "Y", "Z", "a", "ă",
        "â", "b", "c", "d", "đ", "e", "ê",
        "f", "g", "h", "k", "i", "j", "l", "m",
        "n", "o", "ô", "ơ", "p", "q", "r",
        "s", "t", "u", "ư", "v", "w", "x",
        "y", "z", "0", "1", "2", "3", "4",
        "5", "6", "7", "8", "9"
    };
    private List<String> charset;

    private void init() {
        charset = Arrays.asList(charArray);
        pbCreateFile.setStringPainted(true);
        pbCreateFile.setValue(0);
    }

    /**
     * Creates new form Main
     */
    public Main() {
        initComponents();
        init();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        txtImagesPath = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        txtOutPath = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        btnCreate = new javax.swing.JButton();
        btnImagesPath = new javax.swing.JButton();
        btnOutPath = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        lblNumTraining = new javax.swing.JLabel();
        lblNumClass = new javax.swing.JLabel();
        pbCreateFile = new javax.swing.JProgressBar();
        jLabel7 = new javax.swing.JLabel();
        lblCurrent = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        txtTrainingSet = new javax.swing.JTextField();
        btnTrainingSet = new javax.swing.JButton();
        jLabel4 = new javax.swing.JLabel();
        txtAnnConfig = new javax.swing.JTextField();
        btnAnnConfig = new javax.swing.JButton();
        btnTrain = new javax.swing.JButton();
        jLabel8 = new javax.swing.JLabel();
        lblError = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        txtDesireError = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();
        jLabel9 = new javax.swing.JLabel();
        txtNetConfig = new javax.swing.JTextField();
        btnNetConfig = new javax.swing.JButton();
        jLabel10 = new javax.swing.JLabel();
        txtTest = new javax.swing.JTextField();
        btnTest = new javax.swing.JButton();
        btnNetTest = new javax.swing.JButton();
        jLabel11 = new javax.swing.JLabel();
        lblErrorRate = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("zWriteTrainer");
        setLocationByPlatform(true);
        setResizable(false);

        jTabbedPane1.setName("Cummulative Sample File Creator"); // NOI18N

        jLabel1.setText("Thư mục chứa ảnh");

        jLabel2.setText("Thư mục xuất file");

        btnCreate.setText("Tạo bộ huấn luyện");
        btnCreate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCreateActionPerformed(evt);
            }
        });

        btnImagesPath.setText("Chọn thư mục");
        btnImagesPath.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnImagesPathActionPerformed(evt);
            }
        });

        btnOutPath.setText("Chọn thư mục");
        btnOutPath.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnOutPathActionPerformed(evt);
            }
        });

        jLabel5.setText("Số mẫu học");

        jLabel6.setText("Số lớp");

        lblNumTraining.setText("0");

        lblNumClass.setText("0");

        pbCreateFile.setDoubleBuffered(true);
        pbCreateFile.setStringPainted(true);

        jLabel7.setText("Mẫu hiện tại");

        lblCurrent.setText(null);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(btnCreate)
                                .addGap(18, 18, 18)
                                .addComponent(pbCreateFile, javax.swing.GroupLayout.DEFAULT_SIZE, 236, Short.MAX_VALUE))
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel1)
                                    .addComponent(jLabel2))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 49, Short.MAX_VALUE)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(txtOutPath, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
                                    .addComponent(txtImagesPath, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
                                    .addComponent(btnImagesPath)
                                    .addComponent(btnOutPath)))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addGap(134, 134, 134)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel5)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 209, Short.MAX_VALUE)
                                .addComponent(lblNumTraining))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel6)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 246, Short.MAX_VALUE)
                                .addComponent(lblNumClass))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel7)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 209, Short.MAX_VALUE)
                                .addComponent(lblCurrent)))))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(txtImagesPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnImagesPath)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtOutPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnOutPath)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(lblNumTraining))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(lblNumClass))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(lblCurrent))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 57, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(pbCreateFile, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnCreate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Tạo bộ huấn luyện", jPanel1);

        jLabel3.setText("Tập huấn luyện");

        btnTrainingSet.setText("Chọn file");
        btnTrainingSet.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTrainingSetActionPerformed(evt);
            }
        });

        jLabel4.setText("File cấu hình");

        btnAnnConfig.setText("Chọn file");
        btnAnnConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAnnConfigActionPerformed(evt);
            }
        });

        btnTrain.setText("Huấn luyện");
        btnTrain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTrainActionPerformed(evt);
            }
        });

        jLabel8.setText("Chỉ số lỗi");

        lblError.setText("0");

        jLabel12.setText("Lỗi mục tiêu");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnTrain)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 64, Short.MAX_VALUE)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(btnAnnConfig)
                            .addComponent(btnTrainingSet)
                            .addComponent(txtTrainingSet, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
                            .addComponent(txtAnnConfig)))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(109, 109, 109)
                        .addComponent(txtDesireError, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE))
                    .addComponent(jLabel12)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jLabel8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 109, Short.MAX_VALUE)
                        .addComponent(lblError, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(txtTrainingSet, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnTrainingSet)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtAnnConfig, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnAnnConfig)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel12)
                    .addComponent(txtDesireError, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 62, Short.MAX_VALUE)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(lblError))
                .addGap(18, 18, 18)
                .addComponent(btnTrain)
                .addContainerGap())
        );

        jTabbedPane1.addTab("Huấn luyện mạng Neuron", jPanel2);

        jLabel9.setText("File cấu hình mạng");

        btnNetConfig.setText("Chọn file");
        btnNetConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNetConfigActionPerformed(evt);
            }
        });

        jLabel10.setText("File sample test");

        btnTest.setText("Chọn file");
        btnTest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTestActionPerformed(evt);
            }
        });

        btnNetTest.setText("Test mạng Neuron");
        btnNetTest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNetTestActionPerformed(evt);
            }
        });

        jLabel11.setText("Tỉ lệ lỗi:");

        lblErrorRate.setText("0");

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel9)
                            .addComponent(jLabel10))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(btnTest)
                            .addComponent(btnNetConfig)
                            .addComponent(txtNetConfig, javax.swing.GroupLayout.DEFAULT_SIZE, 224, Short.MAX_VALUE)
                            .addComponent(txtTest)
                            .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(jLabel11)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(lblErrorRate))))
                    .addComponent(btnNetTest))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(txtNetConfig, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnNetConfig)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtTest, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnTest)
                .addGap(18, 18, 18)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel11)
                    .addComponent(lblErrorRate))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 87, Short.MAX_VALUE)
                .addComponent(btnNetTest)
                .addContainerGap())
        );

        jTabbedPane1.addTab("Đánh giá mạng Neuron", jPanel3);

        jButton2.setText("Đóng");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setText("Thông tin");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTabbedPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton3)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 320, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton2)
                    .addComponent(jButton3))
                .addContainerGap())
        );

        jTabbedPane1.getAccessibleContext().setAccessibleName("");

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void btnImagesPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnImagesPathActionPerformed
    JFileChooser file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    if (file.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        txtImagesPath.setText(file.getSelectedFile().toString());
    }
}//GEN-LAST:event_btnImagesPathActionPerformed

private void btnOutPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOutPathActionPerformed
    JFileChooser file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    if (file.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        txtOutPath.setText(file.getSelectedFile().toString());
    }
}//GEN-LAST:event_btnOutPathActionPerformed

private void btnCreateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCreateActionPerformed
    if (!txtImagesPath.getText().isEmpty() && !txtOutPath.getText().isEmpty()) {
        new Thread() {

            @Override
            public void run() {
                int numInput = 41;
                int numTrainingSet = 0;
                int numClass;
                File path = new File(txtImagesPath.getText());
                File output = new File(txtOutPath.getText());
                DataOutputStream writer;
                String[] fileList;

                pbCreateFile.setValue(0);

                try {
                    writer = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(output + System.getProperty("file.separator") + "trainingset.ts")));
                    if (path.isDirectory()) {
                        fileList = path.list();
                        for (int i = 0; i < fileList.length; i++) {
                            if (fileList[i].contains(".txt")) {
                                numTrainingSet++;
                            }
                        }
                        numClass = charset.size();
                        lblNumClass.setText(String.valueOf(numClass));
                        lblNumTraining.setText(String.valueOf(numTrainingSet));
                        invalidate();

                        writer.writeInt(numInput);
                        writer.writeInt(numClass);
                        writer.writeInt(numTrainingSet);


                        for (int i = 0; i < fileList.length; i++) {
                            if (fileList[i].contains(".txt")) {
                                lblCurrent.setText(fileList[i]);
                                pbCreateFile.setValue(i * 100 / numTrainingSet);
                                invalidate();
                                double[] input = Feature.importFeatureType01(path.getPath() + System.getProperty("file.separator") + fileList[i]);
                                double[] target = Util.DoubleBinaryTargetArray(charset.indexOf(fileList[i].substring(0, 1)), numClass);
                                for (int j = 0; j < numInput; j++) {
                                    writer.writeDouble(input[j]);
                                }

                                System.out.printf(fileList[i] + "\n");

                                for (int j = 0; j < numClass; j++) {
                                    writer.writeDouble(target[j]);
                                }
                            }
                            //E:\Project\Project 122011\zWriteTrainer\ImageCharset
                        }
                    }
                    writer.close();
                    JOptionPane.showMessageDialog(null, "Hoàn thành tạo file huấn luyện!");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}//GEN-LAST:event_btnCreateActionPerformed
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
    System.exit(0);
}//GEN-LAST:event_jButton2ActionPerformed

private void btnTrainingSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTrainingSetActionPerformed
    JFileChooser file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.FILES_ONLY);
    if (file.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        txtTrainingSet.setText(file.getSelectedFile().toString());
    }
}//GEN-LAST:event_btnTrainingSetActionPerformed

private void btnAnnConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAnnConfigActionPerformed
    JFileChooser file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    if (file.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        txtAnnConfig.setText(file.getSelectedFile().toString());
    }
}//GEN-LAST:event_btnAnnConfigActionPerformed

private void btnTrainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTrainActionPerformed
    if (!txtTrainingSet.getText().isEmpty() && !txtAnnConfig.getText().isEmpty()) {
        new Thread() {

            @Override
            public void run() {
                try {
//                    TrainingSet trainingSet = TrainingSet.importTrainingExamplesFromFile(txtTrainingSet.getText());
//                    Network network = new Network();
//                    network.addLayer(new Layer(41, 50, network, 0.01, new SigmoidMethod()));
//                    network.addLayer(new Layer(50, 76, network, 0.01, new SigmoidMethod()));
                    double desireError = 0.001;

                    BasicNetwork network = new BasicNetwork();
                    network.addLayer(new BasicLayer(null, false, 41));
                    network.addLayer(new BasicLayer(new ActivationTANH(), true, 50));
                    network.addLayer(new BasicLayer(new ActivationTANH(), true, charset.size()));
                    network.getStructure().finalizeStructure();
                    network.reset();
                    HashMap<String, double[][]> data = Util.importTrainingData(txtTrainingSet.getText());
                    MLDataSet trainingSet = new BasicMLDataSet(data.get("input"), data.get("output"));
                    //final MLTrain train = new LevenbergMarquardtTraining(network, trainingSet);
                    final MLTrain train = new ResilientPropagation(network, trainingSet);
                    if (!txtDesireError.getText().isEmpty()) {
                        desireError = Double.valueOf(txtDesireError.getText());
                    }
                    int epochs = 1;


                    do {
                        train.iteration();
                        lblError.setText(String.valueOf(train.getError()));
                        epochs++;
                    } while (train.getError() > desireError);
                    EncogDirectoryPersistence.saveObject(new File(txtAnnConfig.getText()+System.getProperty("file.separator")+"netconfig"), network);
                    JOptionPane.showMessageDialog(null, "Đã huấn luyện xong!Lỗi: " + train.getError() + "-Epochs:" + epochs);
//                    network.exportNetworkToFile(txtAnnConfig.getText()+"\\netconfig01.ann");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }.start();
    }
}//GEN-LAST:event_btnTrainActionPerformed

private void btnNetConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNetConfigActionPerformed
    JFileChooser file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.FILES_ONLY);
    if (file.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        txtNetConfig.setText(file.getSelectedFile().toString());
    }
}//GEN-LAST:event_btnNetConfigActionPerformed

private void btnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTestActionPerformed
    JFileChooser file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.FILES_ONLY);
    if (file.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        txtTest.setText(file.getSelectedFile().toString());
    }
}//GEN-LAST:event_btnTestActionPerformed

private void btnNetTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNetTestActionPerformed
    try {
        if (!txtNetConfig.getText().isEmpty() && !txtTest.getText().isEmpty()) {
            BasicNetwork network = (BasicNetwork)EncogDirectoryPersistence.loadObject(new File(txtNetConfig.getText()));
            HashMap<String, double[][]> data = Util.importTrainingData(txtTest.getText());
            MLDataSet trainingSet = new BasicMLDataSet(data.get("input"), data.get("output"));
            double error = network.calculateError(trainingSet);
            lblErrorRate.setText(String.valueOf(error));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}//GEN-LAST:event_btnNetTestActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;




                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Main().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAnnConfig;
    private javax.swing.JButton btnCreate;
    private javax.swing.JButton btnImagesPath;
    private javax.swing.JButton btnNetConfig;
    private javax.swing.JButton btnNetTest;
    private javax.swing.JButton btnOutPath;
    private javax.swing.JButton btnTest;
    private javax.swing.JButton btnTrain;
    private javax.swing.JButton btnTrainingSet;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JLabel lblCurrent;
    private javax.swing.JLabel lblError;
    private javax.swing.JLabel lblErrorRate;
    private javax.swing.JLabel lblNumClass;
    private javax.swing.JLabel lblNumTraining;
    private javax.swing.JProgressBar pbCreateFile;
    private javax.swing.JTextField txtAnnConfig;
    private javax.swing.JTextField txtDesireError;
    private javax.swing.JTextField txtImagesPath;
    private javax.swing.JTextField txtNetConfig;
    private javax.swing.JTextField txtOutPath;
    private javax.swing.JTextField txtTest;
    private javax.swing.JTextField txtTrainingSet;
    // End of variables declaration//GEN-END:variables
}
